package com.smalluz.ad.modules.common.util.json;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.SerializationFeature;

public class JacksonUtils {

    private static JsonObjectMapper mapper;
    // 专门用户将驼峰命名值转换成下滑线字段
    private static JsonObjectMapper mapper2;

    static {
        if (mapper == null) {
            mapper = new JsonObjectMapper(false);
            mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        }
        if (mapper2 == null) {
            mapper2 = new JsonObjectMapper(true);
            mapper2.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        }
    }
 

    /**
     * json 转换成List 对象集合
     *
     * @param json
     * @param Tbject
     * @return
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws IOException
     */
    public static <T> ArrayList<T> jsn2List(String json, T Tbject) throws JsonParseException, JsonMappingException, IOException {
        // return mapper.readValue(json, new TypeReference<ArrayList<T>>() {
        // });
        JavaType javaType = getCollectionTypeOnList(ArrayList.class, Tbject.getClass());
        return mapper.readValue(json, javaType);
    }

    /**
     * json 转换成List 对象集合
     *
     * @param json
     * @param clazz
     * @return
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws IOException
     */
    public static <T> ArrayList<T> jsn2List(String json, Class<T> clazz) throws JsonParseException, JsonMappingException, IOException {
        // return mapper.readValue(json, new TypeReference<ArrayList<T>>() {
        // });
        JavaType javaType = getCollectionTypeOnList(ArrayList.class, clazz);
        return mapper.readValue(json, javaType);
    }

    /**
     * 获取泛型的Collection Type
     *
     * @param collectionClass 泛型的Collection
     * @param elementClasses 元素类
     * @return JavaType Java类型
     * @since 1.0
     */
    public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
        return mapper.getTypeFactory().constructArrayType(collectionClass);
    }

    public static JavaType getCollectionTypeOnList(Class<?> collectionClass, Class<?>... elementClasses) {
        return mapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
    }

    /**
     * json String transform entity
     *
     * @param jsonparam
     * @param clazz
     * @return
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws IOException
     */
    public static <T> T jsn2bean(String jsonparam, Class<T> clazz) {
        try {
            return mapper.readValue(jsonparam, clazz);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * json 转换成指定类型的map
     *
     * @author zhuzhancai E-mail:510711793@qq.com
     * @version
     * @time：2015年12月23日 下午1:23:30
     * @description
     * @param json
     * @param keyClass
     * @param valueClass
     * @return
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws IOException
     */
    public static <tKkey, tValue> Map<tKkey, tValue> jsn2map(String json, Class<tKkey> keyClass, Class<tValue> valueClass) {
        try {
            return mapper.readValue(json, new TypeReference<HashMap<tKkey, tValue>>() {});
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * json 转换成List/ map 泛型对象 对象集合
     *
     * @param json
     * @param keyClass
     * @return
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws IOException
     */
    public static  <tKkey, tValue> List<HashMap<tKkey, tValue>>  jsn2MapList(String json, Class<tKkey> keyClass, Class<tValue> valueClass )  {
        try {
            return mapper.readValue(json,new TypeReference<List<HashMap<tKkey, tValue>>>() {});
        } catch (JsonMappingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JsonProcessingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return null;
    }


    /**
     *
     * @param Tbject
     * @return
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws IOException
     */
    public static <T> String bean2Jsn(T Tbject) {
        try {
            return mapper.writeValueAsString(Tbject);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将bean转换成map
     *
     * @param Tbject
     * @param keyClass
     * @param valueClass
     * @return
     * @throws Exception
     */
    public static <tKkey, tValue> Map<tKkey, tValue> bean2UnderlineMap(Object Tbject, Class<tKkey> keyClass, Class<tValue> valueClass)
            throws Exception {
        String json = bean2JsnUnderscores(Tbject);
        return jsn2map(json, keyClass, valueClass);
    }

    

    /**
     * 驼峰和下划线互转
     *
     * @param Tbject
     * @return
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws IOException
     */
    public static <T> String bean2JsnUnderscores(T Tbject) throws JsonParseException, JsonMappingException, IOException {
        return mapper2.writeValueAsString(Tbject);
    }

    /**
     * Title: bean2JsnUnderscoresPrettyPrinter Description:美化输出格式
     *
     * @param Tbject
     * @return
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws IOException
     */
    public static <T> String bean2JsnUnderscoresPrettyPrinter(T Tbject) throws JsonParseException, JsonMappingException, IOException {
        return mapper2.writerWithDefaultPrettyPrinter().writeValueAsString(Tbject);
    }

    /**
     * json String transform entity 驼峰和下划线互转
     *
     * @param jsonparam
     * @param clazz
     * @return
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws IOException
     */
    public static <T> T jsn2beanUnderscores(String jsonparam, Class<T> clazz) throws JsonParseException, JsonMappingException, IOException {
        return mapper2.readValue(jsonparam, clazz);
    }


}
